package org.net.loader
{
	
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.utils.ByteArray;
	
	/**
	 * Abstract Resource Loader
	 */
	public class ResLoader extends ALoader
	{	
		protected var _stream : URLStream;
		
		//load content
		protected var _byteArray : ByteArray;
		
		
		public function ResLoader(data:ResourceData)
		{
			super(data);
		}
		
		
		private function addStreamEvents() : void {
			_stream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			_stream.addEventListener(Event.COMPLETE, completeHandler);
			_stream.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			_stream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
		}
		
		private function removeStreamEvents() : void {
			_stream.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
			_stream.removeEventListener(Event.COMPLETE, completeHandler);
			_stream.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			_stream.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
		}
		
		
		/**
		 * load()
		 */
		override public function load() : void {
			if (_isLoading || _isLoaded) {
				return;
			}
			
			_isLoading = true;
			_stream = new URLStream();
			addStreamEvents();
			_loadProgress.reset();
			var request : URLRequest = new URLRequest(_resData.url);
			_stream.load(request);
		}
		
		
		private function progressHandler(event : ProgressEvent) : void {
			_loadProgress.calcPercent(event.bytesLoaded, event.bytesTotal);
		}
		
		
		private function completeHandler(event : Event) : void {
			removeStreamEvents();
			_byteArray = new ByteArray();
			var length : int = _stream.bytesAvailable;
			_stream.readBytes(_byteArray, 0, length);
			_stream.close();
			onComplete();
		}
		
		
		private function securityErrorHandler(event : SecurityErrorEvent) : void {
			onError(event.text);
		}
		
		protected function onComplete() : void {
			_isLoading = false;
			_isLoaded = true;
			trace("load complete:" + _resData.url);
			dispatchEvent(new Event(Event.COMPLETE));
		}
		
		
		private function ioErrorHandler(event : IOErrorEvent) : void {
			onError(event.text);
		}
		
		
		protected function onError(message : String) : void {
			removeStreamEvents();
			trace("load error:" + _resData.url);
			var event : ErrorEvent = new ErrorEvent(ErrorEvent.ERROR);
			event.text = message;
			dispatchEvent(event);
		}
		
	}
}